package br.com.gbvbahia.bluetooth;

import java.io.IOException;
import java.util.Date;
import java.util.Set;
import java.util.UUID;

import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothServerSocket;
import android.bluetooth.BluetoothSocket;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;

/*
 * http://developer.android.com/guide/topics/connectivity/bluetooth.html
 */
public class BlootoothActivity extends Activity {

	private TextView text;
	private TextView text2;
	private TextView text3;
	private LinearLayout layout;
	private LinearLayout layout2;
	private Button btBuscarBluetoothPareados;
	private Button btScanBluetooth;
	private Button btDescobertaHabBluetooth;
	// Socket
	private BluetoothSocket socketBluetooth = null;
	/**
	 * Alterando status de disponibilidade de descoberta
	 */
	private final BroadcastReceiver bluetoothBroadcastDiscoverable = new BroadcastReceiver() {
		public void onReceive(Context context, Intent intent) {
			String action = intent.getAction();
			// When discovery finds a device
			if (BluetoothAdapter.ACTION_SCAN_MODE_CHANGED.equals(action)) {
				int mode = intent.getIntExtra(BluetoothAdapter.EXTRA_SCAN_MODE,
						BluetoothAdapter.ERROR);
				String strMode = "";
				switch (mode) {
				case BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE:
					strMode = "mode changed: SCAN_MODE_CONNECTABLE_DISCOVERABLE";
					break;
				case BluetoothAdapter.SCAN_MODE_CONNECTABLE:
					strMode = "mode changed: SCAN_MODE_CONNECTABLE";
					break;
				case BluetoothAdapter.SCAN_MODE_NONE:
					strMode = "mode changed: SCAN_MODE_NONE";
					break;
				}
				text3.setText(strMode);
			} else {
				Log.e("BLUETOO", action);
			}
		}
	};

	// Create a BroadcastReceiver for ACTION_FOUND
	/**
	 * Buscando dispositivos.
	 */
	private final BroadcastReceiver bluetoothBroadcastScan = new BroadcastReceiver() {
		public void onReceive(Context context, Intent intent) {
			String action = intent.getAction();
			// When discovery finds a device
			if (BluetoothDevice.ACTION_FOUND.equals(action)) {
				// Get the BluetoothDevice object from the Intent
				BluetoothDevice device = intent
						.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
				// Add the name and address to an array adapter to show in a
				// ListView
				TextView tv = new TextView(BlootoothActivity.this);
				tv.setText(device.getName() + " :: " + device.getAddress());
				layout2.addView(tv);
			} else {
				Log.e("BLUETOO", action);
			}
		}
	};

	/**
	 * Estado do bluetooth, ligado, desligado, ligando e desligando.
	 */
	private BroadcastReceiver bluetoothBroadcastState = new BroadcastReceiver() {
		@Override
		public void onReceive(Context arg0, Intent intent) {
			final String action = intent.getAction();
			if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
				final int state = intent.getIntExtra(
						BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
				switch (state) {
				case BluetoothAdapter.STATE_OFF:
					text2.setText("Bluetooth desligado");
					break;
				case BluetoothAdapter.STATE_TURNING_OFF:
					text2.setText("Bluetooth desligando...");
					break;
				case BluetoothAdapter.STATE_ON:
					text2.setText("Bluetooth ligado");
					break;
				case BluetoothAdapter.STATE_TURNING_ON:
					text2.setText("Bluetooth ligando...");
					break;
				}
			}
		}
	};

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_blootooth);
		text = (TextView) findViewById(R.id.textHello);
		text2 = (TextView) findViewById(R.id.textHello2);
		text3 = (TextView) findViewById(R.id.textHello3);
		layout = (LinearLayout) findViewById(R.id.layout2);
		layout2 = (LinearLayout) findViewById(R.id.layout3);
		btBuscarBluetoothPareados = (Button) findViewById(R.id.but);
		btScanBluetooth = (Button) findViewById(R.id.but2);
		btDescobertaHabBluetooth = (Button) findViewById(R.id.but3);
		btBuscarBluetoothPareados.setOnClickListener(new View.OnClickListener() {
					@Override
					public void onClick(View v) {
						// BLUETOOTH
						addPairedDevices();
					}
				});
		btScanBluetooth.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				// BLUETOOTH_ADMIN
				scanBlueTooth();
			}
		});
		btDescobertaHabBluetooth.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				habilitarDescoberta();
			}
		});
		// Regitro do Receiver ou Broadcast
		this.registerReceiver(this.bluetoothBroadcastState, new IntentFilter(
				BluetoothAdapter.ACTION_STATE_CHANGED));
		this.registerReceiver(this.bluetoothBroadcastScan, new IntentFilter(
				BluetoothDevice.ACTION_FOUND));
		this.registerReceiver(this.bluetoothBroadcastDiscoverable,
				new IntentFilter(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED));
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.blootooth, menu);
		return true;
	}

	@Override
	protected void onResume() {
		super.onResume();
		/*
		 * Nao precisa de autorizacao: android.permission.BLUETOOTH para
		 * utilizar ate aqui.
		 */
		BluetoothAdapter mBluetoothAdapter = BluetoothAdapter
				.getDefaultAdapter();
		if (mBluetoothAdapter == null) {
			text.setText("Bluetooth nao disponivel");
		} else {
			/*
			 * precisa de autorizacao: android.permission.BLUETOOTHa partir da
			 * execucao: mBluetoothAdapter.isEnabled()
			 */
			addPairedDevices();
		}
	}

	/**
	 * Habilita o bluetooth local a ser visto por outros nao pareados.
	 */
	private void habilitarDescoberta() {
		Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
		discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 60);
		startActivity(discoverableIntent);
	}

	/**
	 * Necessita de BLUETOOTH_ADMIN no AndroidManifest para ser chamando
	 */
	private void scanBlueTooth() {
		layout2.removeAllViews();
		BluetoothAdapter mBluetoothAdapter = BluetoothAdapter
				.getDefaultAdapter();
		if (mBluetoothAdapter != null && mBluetoothAdapter.isEnabled()) {
			mBluetoothAdapter.startDiscovery();
		}
	}

	/**
	 * Necessita de BLUETOOTH no AndroidManifest para ser chamando Se houver
	 * bluetooth e ele estiver ligado procura dispositivos pareados e os coloca
	 * em tela.
	 */
	private void addPairedDevices() {
		BluetoothAdapter mBluetoothAdapter = BluetoothAdapter
				.getDefaultAdapter();
		if (mBluetoothAdapter != null && mBluetoothAdapter.isEnabled()) {
			text.setText("Bluetooth disponivel e ligado");
			Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
			layout.removeAllViews();
			if (pairedDevices.size() > 0) {
				TextView tvInfo = new TextView(this);
				tvInfo.setText("Dispositivos Pareados:");
				layout.addView(tvInfo);
				// Loop through paired devices
				for (BluetoothDevice device : pairedDevices) {
					TextView tv = new TextView(this);
					tv.setText(device.getName() + " :: " + device.getAddress());
					layout.addView(tv);
				}
			} else {
				text.setText("Nao existem dispositivos pareados.");
			}
		} else {
			text.setText("Bluetooth disponivel mas nao esta ligado");
		}
	}

	@Override
	protected void onPause() {
		super.onPause();
		if (isFinishing()) {
			this.unregisterReceiver(bluetoothBroadcastState);
			this.unregisterReceiver(bluetoothBroadcastScan);
			this.unregisterReceiver(bluetoothBroadcastDiscoverable);
		}
	}

	private class AcceptThread extends Thread {
		private final BluetoothServerSocket mmServerSocket;

		public AcceptThread(BluetoothAdapter mBluetoothAdapter) {
			// Use a temporary object that is later assigned to mmServerSocket,
			// because mmServerSocket is final
			BluetoothServerSocket tmp = null;
			try {
				// MY_UUID is the app's UUID string, also used by the client
				// code
				tmp = mBluetoothAdapter.listenUsingRfcommWithServiceRecord("BlootoothActivity",
						new UUID(new Date().getTime(), new Date().getTime()));
			} catch (IOException e) {
			}
			mmServerSocket = tmp;
		}

		public void run() {
			BluetoothSocket socket = null;
			// Keep listening until exception occurs or a socket is returned
			while (true) {
				try {
					socket = mmServerSocket.accept();
					// If a connection was accepted
					if (socket != null) {
						// Do work to manage the connection (in a separate thread)
						socketBluetooth = socket;
						mmServerSocket.close();
						break;
					}
				} catch (Exception e) {
					Log.e("Bluetooth", e.getMessage(), e);
					break;
				}
			}
		}

		/** Will cancel the listening socket, and cause the thread to finish */
		public void cancel() {
			try {
				mmServerSocket.close();
			} catch (IOException e) {
			}
		}
	}

}
